<template>
  <div class="all">
    <div id="three-box" @mousedown="onmousedown" @mouseup="onmouseup"></div>
    <tip-box ref="lablebox"></tip-box>
  </div>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; // 控制器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { PMREMGenerator, UnsignedByteType } from "three";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
// import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls'
// import * as dat from "dat.gui";
/* eslint-disable */
// const gui = new dat.GUI();
var scene, camera, renderer, mesh, controls, flowingLineTexture; // 将场景等变量定义在全局，尽量不要挂载到vue实例上
// onresize 事件会在窗口被调整大小时发生
class PickHelper {
  constructor() {
    this.raycaster = new THREE.Raycaster();
    this.pickedObject = null;
    this.pickedObjectSavedColor = 0;
  }
  pick(normalizedPosition, scene, camera) {
    // 恢复上一个被拾取对象的颜色
    // if (this.pickedObject) {
    //   this.pickedObject.material.emissive.setHex(this.pickedObjectSavedColor);
    //   this.pickedObject = undefined;
    // }
    // 发出射线
    this.raycaster.setFromCamera(normalizedPosition, camera);
    // 获取与射线相交的对象
    const intersectedObjects = this.raycaster.intersectObjects(scene.children);
    if (intersectedObjects.length) {
      return intersectedObjects[0];
    }
  }
}
var pickHelper = new PickHelper();
export default {
  name: "ThreeTest",
  props: {
    openGetPoint: {
      type: Boolean,
      default: false,
    },
    floorList: {
      type: Array,
      default: [],
    },
    modelY: {
      type: Number,
      default: -60,
    },
    gxggList: {
      type: Array,
      default: () => [],
    },
    lineList: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      viewSize: {},
      mettingList: [],
      showLables: false,
      hy1: { x: 0, y: 0 },
      hy2: { x: 0, y: 0 },
      opCeng: null,
    };
  },
  methods: {
    init() {
      const container = document.getElementById("three-box");
      this.viewSize = {
        width: container.clientWidth,
        height: container.clientHeight,
      };
      camera = new THREE.PerspectiveCamera(
        45,
        container.clientWidth / container.clientHeight,
        1,
        5000
      );
      scene = new THREE.Scene();
      camera.position.set(8.5, 1.2, -4);
      camera.lookAt(new THREE.Vector3(10,1,-4)); //设置相机方向(指向的场景对象)
      // scene.add(new THREE.AxesHelper(250));
      // scene.add(new THREE.AmbientLight(0xfdf5e6, 1)); //环境光
      // scene.add(new THREE.AmbientLight(0x6bb0d3, 0.5)); //环境光
      // scene.add(new THREE.AmbientLight(0xfdf5e6, 0.5)); //环境光

      // const point1 = new THREE.DirectionalLight(0x6bb0d3, 3); //FDF5E6光源设置
      // point1.position.set(-40, -40, -40); //点光源位置
      // scene.add(point1); //将光源添加到场景中

      const point2 = new THREE.DirectionalLight(0xfdf5e6, 1); //FDF5E6光源设置
      point2.position.set(-10, -10, 10); //点光源位置
      scene.add(point2); //将光源添加到场景中
      // const point3 = new THREE.DirectionalLight(0x6bb0d3, 1); //FDF5E6光源设置
      // point3.position.set(40, 40, 40); //点光源位置
      // scene.add(point3); //将光源添加到场景中
      // const point4 = new THREE.DirectionalLight(0x6bb0d3, 1); //FDF5E6光源设置
      // point4.position.set(30, 30, 0); //点光源位置
      // scene.add(point4); //将光源添加到场景中

      this.addGltf();

      renderer = new THREE.WebGLRenderer({
        antialias: true,
      });
      renderer.setClearColor(0x000000, 0.8); //设置背景颜色
      renderer.setSize(container.clientWidth, container.clientHeight);
      container.appendChild(renderer.domElement);
      this.renderView();
      // controls = new PointerLockControls( camera, renderer.domElement );
      // scene.add(controls.getObject())
      controls = new OrbitControls(camera, renderer.domElement); //创建控件对象

      controls.target = new THREE.Vector3(0, 0, 0);
      controls.maxDistance = 10;
      controls.maxPolarAngle = Math.PI / 2.2;
      // const geometry = new THREE.BoxGeometry(1, 1, 1) //创建一个立方体几何对象Geometry
      // scene.add(geometry) //
    },
    renderView() {
      renderer.render(scene, camera); //执行渲染操作
      // this.hy1 = this.vchange({ x: 13, y: 3, z: 16 });
      if (flowingLineTexture) {
        flowingLineTexture.offset.x -= 0.02; //更新流动线纹理偏移量
      }
      requestAnimationFrame(this.renderView); //请求再次执行渲染函数render
    },
    floorClick(val) {
      console.log(val);
    },
    vchange(vec) {
      const vectCube = new THREE.Vector3(vec.x, vec.y, vec.z);
      const posiCube = vectCube.project(camera);

      let halfWidth = window.innerWidth / 2,
        halfHeight = window.innerHeight / 2;

      const das = {
        x: posiCube.x.toFixed(2) * halfWidth + halfWidth,
        y: -posiCube.y.toFixed(2) * halfHeight + halfHeight,
      };

      return das;
    },
    changeScene(val) {
      const { pos, cmpos } = val;
      camera.position.set(cmpos.x, cmpos.y, cmpos.z);
      controls.target = new THREE.Vector3(pos.x, pos.y, pos.z);
      camera.lookAt(new THREE.Vector3(pos.x, pos.y, pos.z)); //设置相机方向(指向的场景对象)
    },
    addlable() {
      const pmremGenerator = new PMREMGenerator(renderer); // 使用hdr作为背景色
      pmremGenerator.compileEquirectangularShader();
      new RGBELoader()
        .setDataType(UnsignedByteType)
        .load("/map/test/hdr.tif", function (texture) {
          const envMap = pmremGenerator.fromEquirectangular(texture).texture;
          // envMap.isPmremTexture = true;
          pmremGenerator.dispose();

          scene.environment = envMap; // 给场景添加环境光效果
          scene.background = envMap; // 给场景添加背景图
        });
    },

    addGltf() {
      const loader = new GLTFLoader();
      loader.load(
        window.g.mapUrl,
        (gltf) => {
          // gltf.scene.scale.set(0.01, 0.01, 0.01)
          // gltf.scene.rotation.set(0, 0, 0)
          // gltf.scene.position.set(0, 0, 0);
          console.log(gltf, 1);
          // gltf.scene.castShadow = false
          gltf.scene.traverse(function (child) {
            if (child.isMesh) {
              child.frustumCulled = false;
              //模型阴影
              child.castShadow = true;
              //模型自发光
              child.material.emissive = child.material.color;
              child.material.emissiveMap = child.material.map;
            }
          });
          scene.add(gltf.scene);
        },
        undefined,
        (e) => {
          console.error(e);
        }
      );
    },
    addtestPoint(po) {
      scene.traverse((obj) => {
        if (obj.name === "testGroup") {
          scene.remove(obj);
        }
      });
      const gwGroup = new THREE.Group();
      gwGroup.name = "testGroup";
       
      const mmm = new THREE.SphereGeometry(0.1, 60, 60);
      const nnn = new THREE.MeshBasicMaterial({
        color: 0xf5222d,
      });
      const plane = new THREE.Mesh(mmm, nnn);
      plane.position.set(po.x, po.y, po.z);
      plane.rotation.x = -0.5 * Math.PI;
      gwGroup.add(plane)
      scene.add(gwGroup);
    },
    addmian(list) {
      scene.traverse((obj) => {
        if (obj.name === "gwGroup") {
          scene.remove(obj);
        }
      });
      const gwGroup = new THREE.Group();
      gwGroup.name = "gwGroup";
      list.map((el) => {
        const geometry = new THREE.BoxGeometry(el.size.l, el.size.k, 1);
        const material = new THREE.MeshBasicMaterial({
          color: el.useStatus === 1 ? 0xf5222d : 0x52c41a,
          // side: THREE.DoubleSide,
          opacity: 0.6, //设置透明度
          transparent: true,
        });
        const plane = new THREE.Mesh(geometry, material);
        plane.position.set(el.position.x, el.position.y, el.position.z);
        plane.rotation.x = -0.5 * Math.PI;
        gwGroup.add(plane);

        let canvas = document.createElement("canvas");
        let ctx = canvas.getContext("2d");
        canvas.width = 300;
        canvas.height = 200;

        //设置文字
        ctx.fillStyle = "white";
        ctx.font = 'normal 40px "楷体"';

        ctx.fillText(el.code, 0, 50);
        //生成图片
        let url = canvas.toDataURL("image/png");
        const sprite = new THREE.Sprite(
          new THREE.SpriteMaterial({
            map: new THREE.TextureLoader().load(url), //设置精灵纹理贴图
            side: THREE.DoubleSide,
            transparent: true,
          })
        );
        sprite.scale.set(2, 2, 1); //精灵大小
        sprite.position.set(el.position.x, el.position.y + 0.5, el.position.z);
        gwGroup.add(sprite);

        //将图片构建到纹理中
        // let geometry1 = new THREE.PlaneGeometry(1, 1)
        // let material1 = new THREE.MeshBasicMaterial({
        //   map: new THREE.TextureLoader().load(url),
        //   side: THREE.DoubleSide,
        //   transparent: true,
        // })
        // let rect = new THREE.Mesh(geometry1, material1)
        // rect.rotation.x = -0.5 * Math.PI;
        // rect.position.set(el.position.x, el.position.y+1, el.position.z);
        // gwGroup.add(rect)
      });
      scene.add(gwGroup);

      // gui.add(plane.position, "x", -20, 20).name("物体x坐标");
      // gui.add(plane.position, "y", -20, 20).name("物体y坐标");
      // gui.add(plane.position, "z", -20, 20).name("物体z坐标");
    },
    addAirshow(list) {
      list.forEach((el) => {
        el.po = this.vchange({
          x: el.position.x,
          y: el.position.y,
          z: el.position.z,
        });
      });
      this.$refs.lablebox.init(list);
    },
    addmoveModel() {},
    addPoint(list) {
      console.log(list, 22);
      if (list) {
        this.createTextCanvas(list);
      } else {
        this.createTextCanvas(this.pointList);
      }
    },
    /**
     */
    createTextCanvas(list) {
      scene.traverse((obj) => {
        if (obj.name === "pointGroup") {
          scene.remove(obj);
        }
      });
      const pointGroup = new THREE.Group();
      pointGroup.name = "pointGroup";
      list.map((el) => {
        // 创建精灵模型对象，不需要几何体geometry参数
        const sprite = new THREE.Sprite(
          new THREE.SpriteMaterial({
            map: new THREE.TextureLoader().load(require(`@/assets/${el.icon}`)), //设置精灵纹理贴图
            transparent: true, //开启透明(纹理图片png有透明信息),
            userData: el,
          })
        );
        sprite.scale.set(0.4, 0.4, 0.4); //精灵大小
        const pos = el.position
        sprite.position.set(pos.x, pos.y, pos.z);
        sprite.userData = el
        sprite.name = 'point'
        
        pointGroup.add(sprite);
      });
      scene.add(pointGroup);
    },
    moveToObj(e) {
      let pickPosition = {
        x: (e.clientX / this.viewSize.width) * 2 - 1,
        y: -(e.clientY / this.viewSize.height) * 2 + 1,
      };
      const res = pickHelper.pick(pickPosition, scene, camera);

      this.$emit("moseMoveModel", res);
    },
    onmouseup(e) { 
    },
    // 分层显示
    onmousedown(e) {
      e.preventDefault();
      let objs = [];
      scene.traverse((obj) => {
        if (obj.name === "wsjGroup") {
          console.log(obj, 666);
          obj.children[0].children[0].material.color.set(0xff0);
        }
      });
      let pickPosition = {
        x: (e.clientX / this.viewSize.width) * 2 - 1,
        y: -(e.clientY / this.viewSize.height) * 2 + 1,
      };
      const res = pickHelper.pick(pickPosition, scene, camera);
      console.log(res, "点击事件");
      if(res.object.name == 'point'){
        this.$emit("clickPoint", res.object.userData);
      }
      // this.addtestPoint(res.point)
      this.$emit("clickPosition", res.point);
    },
    addLine(list) {
      //加载纹理
      flowingLineTexture = new THREE.TextureLoader().load(
        require("../../assets/arrow.png")
      );
      flowingLineTexture.wrapS = THREE.RepeatWrapping;
      flowingLineTexture.wrapT = THREE.RepeatWrapping;
      flowingLineTexture.repeat.set(10, 1); //水平重复20次
      flowingLineTexture.needsUpdate = false;
      //创建纹理贴图材质
      list.map((el) => {
        // 创建线条路径 CatmullRomCurve3
        let curve = new THREE.CatmullRomCurve3(
          el.points.map((e) => new THREE.Vector3(e.x, e.y, e.z))
        );

        let material = new THREE.MeshBasicMaterial({
          map: flowingLineTexture,
          side: THREE.DoubleSide,
          transparent: true,
        });
        let mesh = new THREE.Mesh(
          new THREE.TubeGeometry(curve, 30, 0.3, 20),
          material
        );
        mesh.position.y = 0.1;
        scene.add(mesh);
      });
    },
  },

  mounted() {
    this.init();
    window.addEventListener("resize", () => {
      this.viewSize.width = window.innerWidth;
      this.viewSize.height = window.innerHeight;
      renderer.setSize(this.viewSize.width, this.viewSize.height);
      camera.aspect = this.viewSize.width / this.viewSize.height;
      camera.updateProjectionMatrix();
    });
    // window.addEventListener( 'click', this.clickThings, false );
    // this.animate()
    // document.addEventListener( 'keydown', this.onKeyDown())
    // document.addEventListener( 'keyup', this.onKeyUp())
  },
};
</script>
<style scoped>
#three-box {
  height: 100%;
  width: 100%;
}
.laber_name {
  color: #fff;
}
</style>
